package chat

import (
	"sync"
	"sync/atomic"
)

//短连接聊天

func NewChat(cap int) *Chat {
	i := &Chat{cap: cap, max: cap * 2}
	i.rows = i.newRows(0)
	return i
}

type Chat struct {
	cap   int //重置时保留最近条数
	max   int //触发清理时的数据，cap的2倍
	rows  []*Message
	mutex sync.Mutex //仅仅在扩容时使用
	index uint64     //唯一ID种子
}

func (this *Chat) newRows(n int) []*Message {
	return make([]*Message, n, this.max+100)
}

// Add 添加消息
// 清理内存时有可能丢失数据
func (this *Chat) Add(m *Message) {
	if len(this.rows) >= this.max {
		this.mutex.Lock()
		defer this.mutex.Unlock()
		this.reset()
	}
	m.Id = atomic.AddUint64(&this.index, 1)
	this.rows = append(this.rows, m)
}

func (this *Chat) reset() {
	if len(this.rows) < this.max {
		return
	}
	if x := len(this.rows) - this.cap; x > 0 {
		rows := this.newRows(this.cap)
		copy(rows, this.rows[x:])
		this.rows = rows
	}
}

// Get 获取最新聊天信息
// t 上次拉取最后ID，返回当前最大ID
func (this *Chat) Get(t uint64, size int, filter Filter) (n uint64, r []*Message) {
	n = this.index
	if t >= n {
		return
	}

	rows := this.rows
	for i := len(rows) - 1; i >= 0; i-- {
		m := rows[i]
		if m.Id <= t {
			break
		}
		if m.Id > n {
			n = m.Id
		}
		if filter != nil && !filter(m) {
			continue
		}
		r = append(r, m)
		if len(r) >= size {
			break
		}
	}
	return
}

func (this *Chat) Index() uint64 {
	return this.index
}
